﻿using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Feature.Services.CSharp.Bulbs;
using JetBrains.ReSharper.Feature.Services.LiveTemplates.LiveTemplates;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Intentions.Extensibility.Menu;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.Util;

namespace MugenMvvmToolkit.ReSharper.Infrastructure
{
    public abstract class ContextActionImplBase : ContextActionImplBase<ICSharpContextActionDataProvider>
    {
        #region Constructors

        protected ContextActionImplBase([NotNull] ICSharpContextActionDataProvider provider)
            : base(provider)
        {
        }

        #endregion
    }

    public abstract class ContextActionImplBase<TProvider> : IContextAction
        where TProvider : class, IContextActionDataProvider
    {
        #region Constructors

        protected ContextActionImplBase([NotNull] TProvider provider)
        {
            if (provider == null) throw new ArgumentNullException("provider");
            Provider = provider;
            LiveTemplatesManager = LiveTemplatesManager.Instance;
            TypeProvider = TypeProvider.Create(provider.PsiModule, provider.PsiFile.GetResolveContext());
            MethodProvider = MethodProvider.Create(TypeProvider);
            EventProvider = EventProvider.Create(TypeProvider);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the bulb actions.
        /// </summary>
        protected ICollection<IBulbAction> Actions { get; set; }

        /// <summary>
        ///     Gets the provider.
        /// </summary>
        protected TProvider Provider { get; private set; }

        /// <summary>
        ///     Gets the TypeProvider.
        /// </summary>
        protected TypeProvider TypeProvider { get; private set; }

        /// <summary>
        ///     Gets the MethodProvider.
        /// </summary>
        protected MethodProvider MethodProvider { get; private set; }

        /// <summary>
        ///     Gets the EventProvider.
        /// </summary>
        protected EventProvider EventProvider { get; private set; }

        /// <summary>
        ///     Gets the LiveTemplatesManager.
        /// </summary>
        protected LiveTemplatesManager LiveTemplatesManager { get; private set; }

        #endregion

        #region Implementation of IContextAction

        public virtual IEnumerable<IntentionAction> CreateBulbItems()
        {
            return Actions == null ? Enumerable.Empty<IntentionAction>() : Actions.ToContextAction();
        }

        /// <summary>
        ///     Check if this action is available at the constructed context.
        ///     Actions could store precalculated info in <paramref name="cache" /> to share it between different actions
        /// </summary>
        /// <returns>
        ///     true if this bulb action is available, false otherwise.
        /// </returns>
        public abstract bool IsAvailable(IUserDataHolder cache);

        #endregion
    }
}